using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Content;

namespace Fated.BattleEngine {
    // TileSets will be loaded via content
    public class TileSet {
        public string imageFile = "";
        public string heightFile = "";

        private Texture2D image;
        private float[] heightData;

        public bool[] passable;

        public int setWidth = 1;

        public int tileHeight = 25;
        public int tileWidth = 25;

        public void setHeightData(Texture2D heightfile) {
            int dataCount = heightfile.Height * heightfile.Width;
            heightData = new float[dataCount];
            Color[] data = new Color[dataCount];
            heightfile.GetData<Color>(data);
            for (int i = 0; i < dataCount; i++) {
                heightData[i] = (float)data[i].R / 255.0f;
            }
        }

        public Rectangle getTileSource(int index) {
            int x = (index % setWidth) * tileWidth;
            int y = (index / setWidth) * tileHeight;
            return new Rectangle(x, y, tileWidth, tileHeight);
        }
        
        /// <summary>
        /// Returns height at a point in a tile
        /// </summary>
        /// <param name="index">From Tile</param>
        /// <param name="x">From 0 to 1</param>
        /// <param name="y">From 0 to 1</param>
        /// <returns></returns>
        public float getHeight(int index, float x, float y) {
            // Convert tile index to pixel x,y
            int tilex = (index % setWidth) * tileWidth;
            int tiley = (index / setWidth) * tileHeight;
            // Scale percentage by tileSize
            x *= tileWidth;
            y *= tileHeight;
            // Convert tile relative to tilemap absolute 
            // Important to truncate here.
            x = (int)x + tilex;
            y = (int)y + tiley;
            // Convert pixel x,y to linear index
            // Shifting down one is shifting across 
            // one setwidth of tiles at tileheight's pixel per tile
            index = (int)(y * tileHeight * setWidth + x);

            return heightData[index];
        }
    }
    public class Tile {
        public int tileIndex = 0;
        public int height = 0;
    }
    public class BattleMap : AbstractMap {
        private TileSet mapTileSet;
        public string tileSetName;
        public Tile[][] mapData;
        private TurnData[][] characters;

        public void setup(ContentManager cM, List<TurnData> initial) {
            cursor = new Point(0, 0);
            mapTileSet = cM.Load<TileSet>(tileSetName);
            characters = new TurnData[getWidth()][];
            for (int i = 0; i < characters.Length; ++i) {
                characters[i] = new TurnData[getHeight()];
            }
            foreach (TurnData d in initial){
                characters[(int)d.npcData.X][(int)d.npcData.Y] = d;
            }
        }

        public override string getCharacter(int x, int y) {
            String output = null;
            if (containsCharacter(x, y)) {
                output = characters[x][y].npcData.Name;
            }
            return output;
        }
        public void moveCharacter(Point charAt) {
            characters[cursor.X][cursor.Y] = characters[charAt.X][charAt.Y];
            characters[charAt.X][charAt.Y] = null;
            characters[cursor.X][cursor.Y].npcData.X = cursor.X;
            characters[cursor.X][cursor.Y].npcData.Y = cursor.Y;
        }
        public bool containsCharacter() {
            return characters[cursor.X][cursor.Y] != null;
        }
        public override bool containsCharacter(int x, int y) {
            return characters[x][y] != null;
        }
        public override string getTileset() {
            return mapTileSet.imageFile;
        }
        public override Rectangle getTileSize() {
            return new Rectangle(0, 0, mapTileSet.tileWidth, mapTileSet.tileHeight);
        }
        public override int getTileHeight(int x, int y) {
            return mapData[(int)x][(int)y].height;
        }
        public override int getHeight() { return mapData[0].Length; }
        public override int getWidth() { return mapData.Length; }
        public override int getTile(int x, int y) {
            return mapData[x][y].tileIndex;
        }
    }
}
